// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <functional>
#include <memory>
#include <string>

namespace Aws::Auth {
// Forward-declare the AWSCredentialsProvider class from the AWS SDK.
class AWSCredentialsProvider;
} // namespace Aws::Auth

namespace kumo::pollux::config {
class ConfigBase;
}

namespace kumo::pollux::filesystems {

using CacheKeyFn = std::function<
    std::string(std::shared_ptr<const config::ConfigBase>, std::string_view)>;

// Register the S3 filesystem.
void registerS3FileSystem(CacheKeyFn cacheKeyFunc = nullptr);

void registerS3Metrics();

/// Teardown the AWS SDK C++.
/// Pollux users need to manually invoke this before exiting an application.
/// This is because Pollux uses a static object to hold the S3 FileSystem
/// instance. AWS C++ SDK library also uses static global objects in its code.
/// The order of static object destruction is not determined by the C++
/// standard.
/// This could lead to a segmentation fault during the program exit.
/// Ref https://github.com/aws/aws-sdk-cpp/issues/1550#issuecomment-1412601061
void finalizeS3FileSystem();

class S3Config;

using AWSCredentialsProviderFactory =
    std::function<std::shared_ptr<Aws::Auth::AWSCredentialsProvider>(
        const S3Config& config)>;

void registerAWSCredentialsProvider(
    const std::string& providerName,
    const AWSCredentialsProviderFactory& provider);

} // namespace kumo::pollux::filesystems
